/*********************************************************
          File Name:timer.h
          Author: Abby Cin
          Mail: abbytsing@gmail.com
          Created Time: Tue 29 Sep 2015 10:06:39 AM CST
**********************************************************/

#ifndef TIMER_H_
#define TIMER_H_

#include <iostream>
#include <string>
#include <iomanip>
#include <sstream>
#include <ctime>

class Timer
{
        private:
                void refresh()
                {
                        min += int(sec / 60);
                        sec = sec % 60;
                        hour += int(min / 60);
                        min = min % 60;
                }

                std::string format(int n, int precision = 2)
                {
                        std::stringstream s;
                        s << std::setfill('0') << std::setw(precision) << n;
                        return s.str();
                }

       public:
                int hour;
                int min;
                int sec;
                int msec;               //  not use

                std::string month;
                std::string day_of_week;
                std::string day_of_month;
                std::string year;

        public:

                Timer();
                Timer(int, int, int, int ms = 0);
                
                Timer(Timer &a)
		{
			hour = a.hour;
			min = a.min;
			sec = a.sec;
			msec = a.msec;
		}
                Timer(const Timer &a)
		{
			hour = a.hour;
			min = a.min;
			sec = a.sec;
			msec = a.msec;
		}
                ~Timer() {}

                Timer &operator=(Timer &);
                Timer &operator+(int);
                bool operator>(Timer &);
                bool operator<(Timer &);
                friend std::ostream &operator<<(std::ostream &os, Timer &t)
                {
                        os << t.hour << ":" << t.min << ":" << t.sec << ":" << t.msec;
                        return os;
                } 

                // convert time to seconds
                long to_sec();

                // a helper function to re-init time
                void set_time(int h, int m, int s, int ms = 0)
                {
                        hour = h;
                        min = m;
                        sec = s;
                        msec = (ms == 0 ? 0 : ms);
                }
                // overload above 
                void set_time(std::string t);    // format: 09:15:00, 15:30:12
                // enlarge time 
                void add(int sec);      // member version, to `Timer &operator+(int)`

                // if current is between a duraction (start, end)
                bool is_between(Timer &, Timer&);

                // get localtime 
                Timer &update();
                // same as `set_time()`
                Timer &update(int h, int m, int s, int ms = 0);
                // time interval, this->to_sec() - time_point.to_sec()
                long interval(Timer &);
		
		long eta(Timer &t)
		{
			return this->to_sec() - t.to_sec();
		}

                std::string get_time(bool full = false);

                std::string get_day()
                {
                        time_t tmp;
                        tmp = time(NULL);
                        char today[25] = {0};
                        strftime(today, 25, "%Y%m%d", localtime(&tmp));
                        return std::string(today);
                }

                bool is_leap_year(int);

                int find_date_by_wday(int, int, int, int);
};

#endif
